﻿package ua.mihaylenko.canvas.gui.photoshop.canvas 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import gs.TweenFilterLite;
	import ua.mihaylenko.canvas.common.DocumentClass;
	import ua.mihaylenko.canvas.data.DataManager;
	import ua.mihaylenko.canvas.gui.dscene.GUI3ds;
	import ua.mihaylenko.canvas.gui.GUISimpleWindow;
	import ua.mihaylenko.canvas.controller.EventManager;
	import ua.mihaylenko.canvas.controller.CanvasEvent;
	import ua.mihaylenko.canvas.gui.photoshop.GUIPhotoshop;
	/**
	 * ...
	 * @author Mihaylenko A.L.
	 */
	public class GUICanvas extends GUISimpleWindow
	{
		
		public var mcCanvasMask:MovieClip;
		public var _smcPicture:Sprite;
		public var _smcPictureTint:Sprite;
		public var _smcMask:Sprite;
		public var mcQuality:MovieClip;
		public var txtQuality:TextField;
		//public var _smcMask:Sprite;
		
		public var _canFront:Sprite;
		public var _canWidth:Sprite;
		public var _canHeight:Sprite;
		public var _mcRedRect:Sprite;
		
		private var _cRectange:RectangleCanvas;
		private var bitmap:Bitmap;
		private var bitmapTint:Bitmap;
		private var sepia:ColorMatrixFilter;
		private var inch:Number = 2.54;
		private var realBitmapWidth:Number = 0;
		public var container:*;
		
		public static var THIS:GUICanvas;
		public static var NUM_RESIZE_CANVAS:Number;
		public static var NUM_WIDTH_CANVAS:Number;
		public static var NUM_HEIGHT_CANVAS:Number;
		
		public static var W:Number;
		public static var H:Number;
		public static var D:Number;
		public var _smcMaskEdge:MovieClip;
		private var edge:Boolean;
		private var edgeZoom:int;
		private var blnVert:Boolean = true;
		
		public function GUICanvas() 
		{
			addEventListener(Event.ADDED_TO_STAGE, onAdded);
		}
		
		private function onAdded(e:Event):void 
		{
			_smcPicture = container._smcPicture;
			_canFront = container._canFront;
			_canWidth = container._canWidth;
			_canHeight = container._canHeight;
			_mcRedRect = container._mcRedRect;
			_smcPicture = container._smcPicture;
			_smcPictureTint = container._smcPictureTint;
			_smcMask = container._smcMask;
			_smcMaskEdge = container._smcMaskEdge;
			 //= container.;
			container.mask = mcCanvasMask;
			
			
			_cRectange = new RectangleCanvas();
			_cRectange.calculateStepCanvas();
			EventManager.getInstance().addEventListener(CanvasEvent.CHANGE_CANVAS_SIZE, resizeCanvas);
			EventManager.getInstance().addEventListener(CanvasEvent.CHANGE_IMAGE_SIZE, resizeImage);
			mouseChildren = false;
			this.addEventListener(MouseEvent.MOUSE_DOWN, startDragImage);
			this.addEventListener(MouseEvent.MOUSE_UP, stopDragImage);
			
			invisibleAll();
			THIS = this;
			sepia = new ColorMatrixFilter();
			sepia.matrix = [0.3930000066757202, 0.7689999938011169, 0.1889999955892563, 0, 0, 0.3490000069141388, 0.6859999895095825, 0.1679999977350235, 0, 0, 0.2720000147819519, 0.5339999794960022, 0.1309999972581863, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1];
			visible = false;
		}
		public function stretch():void
		{
			//trace("stretc")
			//return;
			var o:Object = {x:_smcPicture.x, y:_smcPicture.y, rotation:_smcPicture.rotation,scaleX:_smcPicture.scaleX} //_smcPicture.visible = .visible = false;
			
			_smcPicture.width = _smcPictureTint.width = 10;
			_smcPicture.scaleY = _smcPictureTint.scaleY = _smcPicture.scaleX;
			
			container.width = 360;
			container.scaleY = container.scaleX;
			
			if (container.height > 360) container.height = 360;
			container.scaleX = container.scaleY;
			
			_smcPicture.x = o.x;
			_smcPicture.y = o.y;
			_smcPicture.rotation = o.rotation;
			_smcPicture.scaleX = _smcPicture.scaleY = o.scaleX;
			
			_smcPictureTint.x = o.x;
			_smcPictureTint.y = o.y;
			_smcPictureTint.rotation = o.rotation;
			_smcPictureTint.scaleX = _smcPictureTint.scaleY = o.scaleX;
			
			
			_smcPicture.visible = _smcPictureTint.visible = true;
			/**/
			
			W = 360; //_mcRedRect.width//*container.scaleX;
			H = _mcRedRect.height/_mcRedRect.width*360  //*container.scaleX;
			D = NUM_RESIZE_CANVAS * container.scaleX;
			
			if (H > 360) {
				var proc:Number = 360 / H;
				H = 360;
				W = W * proc;
				D = D * proc;
			}
			
		}
		private function updateQuality():void 
		{
			var dpi:Number = NUM_HEIGHT_CANVAS / inch;
			
			dpi = realBitmapWidth / dpi;
			//if(bitmap)dpi /= bitmap.scaleX;
			if(_smcPicture)dpi /= _smcPicture.scaleX;
			try 
			{
				
			}catch (e:Error)
			{
				
			}
			
			mcQuality.gotoAndStop(int(dpi));
			
			txtQuality.text = DataManager.getQualityString(dpi);
			
			
			

		}
		private function checkIntersection():void
		{
			if (edge) {
				if (_smcPicture.getBounds(parent).containsRect(_mcRedRect.getBounds(parent))) {
					EventManager.getInstance().dispatchEvent(new Event(CanvasEvent.HIDE_ALERT));
				}else {
					EventManager.getInstance().dispatchEvent(new Event(CanvasEvent.SHOW_ALERT));
				}
			} else {
				var rect:Rectangle = _canHeight.getBounds(parent);
				rect = rect.union(_canWidth.getBounds(parent));
				rect.inflate( -3, -3);
				if (_smcPicture.getBounds(parent).containsRect(rect)) {
					EventManager.getInstance().dispatchEvent(new Event(CanvasEvent.HIDE_ALERT));
				}else {
					EventManager.getInstance().dispatchEvent(new Event(CanvasEvent.SHOW_ALERT));
				}
				
			}
			if(GUI3ds.IS_3D) EventManager.getInstance().dispatchEvent(new Event(CanvasEvent.HIDE_ALERT));
		}
		private function enterFrame(e:Event):void 
		{
			_smcPictureTint.x = _smcPicture.x;
			_smcPictureTint.y = _smcPicture.y;
			DataManager.getInatsnce().imageX = int(_smcPicture.x);
			DataManager.getInatsnce().imageY = int(_smcPicture.y);
			checkIntersection();
		}
		public function rotateImage(value:int):void
		{
			_smcPicture.rotation = value;
			_smcPictureTint.rotation = value;
			
		}
		public function resetZoom():void
		{
			var value:Number = 100;
			if (!edge) value = edgeZoom;
			_smcPicture.scaleX = _smcPicture.scaleY = _smcPictureTint.scaleX = _smcPictureTint.scaleY = value/100;
			DataManager.getInatsnce().zoom = value;
			GUIPhotoshop.THIS._csbZoom.scrollPosition = value;
			updateQuality();
		}
		public function zoomImage(value:int):void
		{
			_smcPicture.scaleX = _smcPicture.scaleY = _smcPictureTint.scaleX = _smcPictureTint.scaleY = value/100;
			DataManager.getInatsnce().zoom = value;
			updateQuality();
		}
		private function stopDragImage(e:MouseEvent):void 
		{
			_smcPicture.stopDrag();
		}
		
		private function startDragImage(e:MouseEvent):void 
		{
			_smcPicture.startDrag(false,new Rectangle(-150,-150, 350,350));
		}
		public function setEdgeOrientation(isInside:Boolean):void 
		{
			edge = isInside;
			if (isInside) {	//small
				_smcPicture.width = _mcRedRect.width;
				_smcPicture.scaleY = _smcPicture.scaleX;
				if (_smcPicture.height < _mcRedRect.height) {
					_smcPicture.height = _mcRedRect.height;
					_smcPicture.scaleX = _smcPicture.scaleY;	
				}
				_smcMaskEdge.visible = true;
				_smcPicture.mask = _smcMaskEdge;
			}else {	//big
				_smcPicture.height = _canHeight.height;
				_smcPicture.scaleX = _smcPicture.scaleY;
				if (_smcPicture.width < _canWidth.width) {
					_smcPicture.width = _canWidth.width;
					_smcPicture.scaleY = _smcPicture.scaleX;
				}
				edgeZoom = (_smcPicture.scaleX) * 100;
				_smcPicture.mask = null;
				_smcMaskEdge.visible = false;
				//GUIPhotoshop.THIS._csbZoom.scrollPosition++;
				
			}
			_smcPictureTint.scaleY = _smcPicture.scaleY;
			_smcPictureTint.scaleX = _smcPicture.scaleX;
			_smcPicture.x = _smcPicture.y = _smcPictureTint.x = _smcPictureTint.y = 0;
			GUIPhotoshop.THIS._csbZoom.scrollPosition = ((_smcPicture.scaleX) * 100);
			GUIPhotoshop.THIS._csbRotate.scrollPosition = 0;
			rotateImage(0);
			stretch()
		}
		
		public function setVerticalOrientation(isVert:Boolean):void 
		{
			trace(blnVert);
			blnVert = isVert;
			var tmpW:int = NUM_WIDTH_CANVAS;
			NUM_WIDTH_CANVAS = NUM_HEIGHT_CANVAS;
			NUM_HEIGHT_CANVAS = tmpW;
			resizeImage(NUM_WIDTH_CANVAS, NUM_HEIGHT_CANVAS, false);
			GUIPhotoshop.THIS._csbRotate.scrollPosition = 0;
			rotateImage(0);
			_smcPicture.x = _smcPicture.y = _smcPictureTint.x = _smcPictureTint.y = 0;
			stretch()
		}
		public function resizeImage(w:Number = 1, h:Number = 1, rot:Boolean = true):void 
		{
			//w = 1000;
			//h = 750;
			NUM_WIDTH_CANVAS = _canFront.width = w;
			NUM_HEIGHT_CANVAS = _canFront.height = h;
			if (!blnVert && rot == true) {
				trace("asasd",blnVert);
				NUM_WIDTH_CANVAS = _canFront.width = h;
				NUM_HEIGHT_CANVAS = _canFront.height = w;
			}
			resizeCanvas(NUM_RESIZE_CANVAS);
			updateQuality();
			stretch();
			_smcPicture.x = _smcPicture.y = _smcPictureTint.x = _smcPictureTint.y = 0;
			resetZoom()
			GUIPhotoshop.THIS._csbRotate.scrollPosition = 0;
			rotateImage(0);
			fitBitmap();
			setEdgeOrientation(edge);
		}
		public function resizeCanvas(w:Number):void {
			NUM_RESIZE_CANVAS = w;
			_canWidth.width = _canFront.width + w * 2;
			_canWidth.height = _canFront.height;
			_canHeight.height = _canFront.height + w * 2;
			_canHeight.width = _canFront.width;
			
			
			_smcMask["_canWidth"].width = _canWidth.width;
			_smcMask["_canWidth"].height = _canWidth.height;
			
			_smcMask["_canHeight"].width = _canHeight.width;
			_smcMask["_canHeight"].height = _canHeight.height;
			
			_smcMask["_canFront"].width = _canFront.width;
			_smcMask["_canFront"].height = _canFront.height;
			
			_mcRedRect.width = _smcMaskEdge.width = _canFront.width;
			_mcRedRect.height = _smcMaskEdge.height = _canFront.height;
			_smcPicture.x = _smcPicture.y = _smcPictureTint.x = _smcPictureTint.y = 0;
			stretch()
			setEdgeOrientation(edge);
		}
		public function get image():BitmapData {
			return null
		}
		public function fitBitmap():void
		{
			
			//bitmap.width = _canFront.width;
			//bitmap.scaleY = bitmap.scaleX;
			//}else {
			//	bitmap.height = _canHeight.height;
			//	bitmap.scaleX = bitmap.scaleY;
			//}
			
			//trace("fiiiiiiiiiiiit", bitmap.width);
			bitmap.width = _mcRedRect.width;
			bitmap.scaleY = bitmap.scaleX;
			if (bitmap.height < _mcRedRect.height) {
				bitmap.height = _mcRedRect.height;
				bitmap.scaleX = bitmap.scaleY;
			}
			
			bitmapTint.scaleY = bitmap.scaleY;
			bitmapTint.scaleX = bitmap.scaleX;
			
			bitmap.x = -bitmap.width / 2;
			bitmap.y = -bitmap.height / 2;
			bitmapTint.x = bitmap.x;
			bitmapTint.y = bitmap.y;
			
			
			stretch();
		}
		public function set image(value:BitmapData) {
			
			if (_smcPicture.numChildren != 0) _smcPicture.removeChildAt(0);
			if (_smcPictureTint.numChildren != 0) _smcPictureTint.removeChildAt(0);
			//if (container.numChildren != 0) container.removeChildAt(0);
			
			bitmap = new Bitmap(value)
			bitmapTint = new Bitmap(value)
			bitmap.smoothing = true;
			realBitmapWidth = bitmap.width;
			_smcPicture.addChild(bitmap);
			_smcPictureTint.addChild(bitmapTint);
			//_smcPicture.x = -bitmap.x;
			//_smcPicture.y = -bitmap.y;
			
			_smcPictureTint.x = _smcPicture.x;
			_smcPictureTint.y = _smcPicture.y;
			
			_smcPicture.visible = true;
			_smcPictureTint.visible = true;
			_smcPictureTint.alpha = 0.3;
			updateQuality();
			visibleAll();
			if (!hasEventListener(Event.ENTER_FRAME)) addEventListener(Event.ENTER_FRAME, enterFrame);
			visible = true;
		}
		public function applySepia() {
			TweenFilterLite.to(_smcPicture, 0.4, { colorMatrixFilter: { hue:340, saturation:0.3 }} );
			sepia.matrix = [0.3930000066757202, 0.7689999938011169, 0.1889999955892563, 0, 0, 0.3490000069141388, 0.6859999895095825, 0.1679999977350235, 0, 0, 0.2720000147819519, 0.5339999794960022, 0.1309999972581863, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1];
			_smcPicture.filters = [sepia];
		}
		public function applyMonochrome() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{saturation:0}});
		}
		public function applyNone() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{saturation:1, contrast:1}});
		}
		public function applyBrighter() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{brightness:1.5}});
		}
		public function applyDarker() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{brightness:0.7}});
		}
		public function applyContrast() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{contrast:2}});
		}
		public function applyThreshold() {
			TweenFilterLite.to(_smcPicture, 0.4, {colorMatrixFilter:{threshold:100}});
		}
		private function invisibleAll():void
		{
			//_canBotom.visible = _canFront.visible = _canLeft.visible = _canRight.visible = _canRight.visible = false;
			_canWidth.visible = _canHeight.visible = false;
		}
		private function visibleAll():void
		{
			_canWidth.visible = _canHeight.visible = true;
		}
		public function set bgColor(value:uint) {
			var ct:ColorTransform = new ColorTransform();
			if( !ct ) ct = new ColorTransform();
			ct.color = value;
			_canWidth.transform.colorTransform = ct;
			_canHeight.transform.colorTransform = ct;
			_canFront.transform.colorTransform = ct;
		}
		
		public function getImageData(s:String):BitmapData 
		{
			visible = true;
			_mcRedRect.visible = false;
			var bmd:BitmapData;
			var matrix:Matrix = new Matrix();
			var scale:Number = container.scaleX;
			
			var h:Number = _canFront.height*scale;
			var w:Number = _canFront.width * scale;
			var d:Number = NUM_RESIZE_CANVAS * scale;
			
			//trace(w, h, scale, W, H);
			container.scaleX = container.scaleY = scale;
			switch (s) 
			{
				case "front":
					bmd = new BitmapData(w, h);
					matrix.createBox(1, 1, 0, w/2, h/2);
					bmd.draw(this, matrix);
				break;
				case "top":
					bmd = new BitmapData(w, d);
					matrix.createBox(1, 1, 0, w/2, h/2+d);
					bmd.draw(this, matrix);
				break;
				case "bottom":
					bmd = new BitmapData(w, d);
					matrix.createBox(-1, -1, 0, w/2, h/2+d);
					bmd.draw(this, matrix);
				break;
				case "left":
					bmd = new BitmapData(d, h);
					matrix.createBox(1, 1, 0, w/2+d, h/2);
					bmd.draw(this, matrix);
				break;
				case "right":
					bmd = new BitmapData(d, h);
					matrix.createBox(1, 1, 0, -w/2, h/2);
					bmd.draw(this, matrix);
				break;
			}
			
			_mcRedRect.visible = true;
			visible = false;
			container.scaleX = container.scaleY = scale;
			return bmd;
			
		}
	}
	
}